/**
 * 用柯里化函数实现一个类型判断
 * 1、常规的方法实现
 * 2、用柯里化函数实现
 */
//常规方法实现一个柯里化函数
//一般需要两个参数类型、值，用值和类型比较
//一般方法是把类型定义为一个集合，遍历这个集合不同类型添加判断类型的方法
/***
 *  方法一：定义好判断的集合，闭包、匿名函数，只需要传入值就可以判断
 *
let Utils = {};
function whatType(typing) {
  return function(val) {
    return Object.prototype.toString.call(val) == `[object ${typing}]`;
  };
}

["String", "Number", "Object", "function"].forEach(row => {
  Utils[`is${row}`] = whatType(row);
});

console.log(Utils.isString("rr")); //true
console.log(Utils.isString(123)); //false
console.log(Utils.isNumber(123)); //true

 */

/**
 * 方法二：
 * 使用柯里化函数
 * 
 */

function whatType(typing, val) {
  console.log(typing, val);
  return Object.prototype.toString.call(val) == `[object ${typing}]`;
}

//v1.0
/*** 
function currying(fn, arr = []) {
  return (...args) => {
    let len = fn.length,
      totalArr = [...arr, ...args]; //参数收集器
    if (len == totalArr.length) {
      return fn(...totalArr);
    } else {
      return currying(fn, args);
    }
  };
}
*/

//v2.0 简易版的柯里化
function currying(fn) {
	const inner = (args = []) => {
		return args.length >= fn.length ? fn(...args) : (...newParams) => inner([...args, ...newParams])
	}
	return inner();
}

let typingFn = currying(whatType);
let isNumber = typingFn("Number");
let isString = typingFn("String");
// console.log(isNumber(123));
console.log(isString("ddd"));
